package com.gugee.common.web.system.promise.validate;

import cn.hutool.core.date.DateUtil;
import com.gugee.common.web.system.promise.model.PermissionRecord;
import com.gugee.common.web.system.promise.repository.PermissionLimitRepository;
import com.gugee.common.web.system.promise.repository.PermissionRecordRepository;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 根据时间限制访问次数
 */
@Slf4j
@Component
public class TimeLimit extends Validate{
    @Autowired
    PermissionLimitRepository permissionLimitRepository;

    @Autowired
    PermissionRecordRepository permissionRecordRepository;

    Lock lock = new ReentrantLock(true);


    /**
     *
     * @param roleId
     * @param params 1.userId 2.TimeType类型 3.属性名称
     * @return
     */
    @Override
    public Boolean validate(long roleId, Object... params) {
        val permissionLimitOptional = permissionLimitRepository.findByPermissionIdAndProductId(super.permissionId, roleId);

        // 没限制
        if(!permissionLimitOptional.isPresent()){
            return true;
        }

        int dateCode = Integer.parseInt(DateUtil.format(new Date(),"yyyyMMdd"));

        // 有记录直接返回
        if(params.length > 2){ //有属性的限制
            if(permissionRecordRepository.
                    findByPermissionLimitIdAndUserIdAndRecordDataAndBelong(permissionLimitOptional.get().getId(),
                            Long.parseLong(params[0].toString()), params[2].toString(),dateCode).isPresent()){
                return true;
            }
        }

        int recordCount = 0;

        if(params[1] == TimeType.DAY){
            recordCount = permissionRecordRepository.
                    countByPermissionLimitIdAndUserIdAndBelong(permissionLimitOptional.get().getId(),Long.parseLong(params[0].toString()),dateCode);
        }else if(params[1] == TimeType.MONTH){
            int startDate = Integer.parseInt(DateUtil.format(DateUtil.beginOfMonth(Calendar.getInstance()).getTime(),"yyyyMMdd"));
            int endDate = Integer.parseInt(DateUtil.format(DateUtil.endOfMonth(Calendar.getInstance()).getTime(),"yyyyMMdd"));
            recordCount = permissionRecordRepository.countByPermissionLimitIdAndUserIdAndBelongBetween(permissionLimitOptional.get().getId(),Long.parseLong(params[0].toString()),startDate,endDate);
        }else if(params[1] == TimeType.YEAR){
            int startDate = Integer.parseInt(DateUtil.format(DateUtil.beginOfYear(Calendar.getInstance()).getTime(),"yyyyMMdd"));
            int endDate = Integer.parseInt(DateUtil.format(DateUtil.endOfYear(Calendar.getInstance()).getTime(),"yyyyMMdd"));
            recordCount = permissionRecordRepository.countByPermissionLimitIdAndUserIdAndBelongBetween(permissionLimitOptional.get().getId(),Long.parseLong(params[0].toString()),startDate,endDate);

        }




        if(recordCount >= permissionLimitOptional.get().getLimitCount()){
            super.tips = permissionLimitOptional.get().getTips();
            return false;
        }



        try{
            lock.lock();
            if(params.length > 2){
                val permissionRecodeOptional = permissionRecordRepository.
                        findByPermissionLimitIdAndUserIdAndRecordDataAndBelong(permissionLimitOptional.get().getId(),
                                Long.parseLong(params[0].toString()), params[2].toString(),dateCode);

                if(permissionRecodeOptional.isPresent()){
                    return true;
                }
            }

            PermissionRecord permissionRecord = new PermissionRecord();
            permissionRecord.setBelong(dateCode);
            permissionRecord.setPermissionLimitId(permissionLimitOptional.get().getId());
            permissionRecord.setUserId(Long.parseLong(params[0].toString()));

            if(params.length > 2){
                permissionRecord.setRecordData(params[2].toString());
            }
            permissionRecord.setCreateBy(params[0].toString());
            permissionRecord.setUpdateBy(params[0].toString());
            permissionRecordRepository.save(permissionRecord);

        }catch (Exception e){
            log.error("error countPropertyLimit error",e);
        }finally {
            lock.unlock();
        }
        return true;
    }

    public enum TimeType{
                DAY(1),
                MONTH(2),
                YEAR(3);

        private int value;
        TimeType(int value){
            this.value = value;
        }
        public int getValue(){
            return this.value;
        }
    }
}
